/*
 * Copyright:  2018 smarabbit studio.
 *
 *  Licensed under the Confluent Community License; you may not use this file
 *  except in compliance with the License.  You may obtain a copy of the License at
 *
 *  http://www.confluent.io/confluent-community-license
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OF ANY KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations under the License.
 *
 *  @作   者： 黄开晖 (117227773@qq.com)
 *  @日   期:  2020年8月31日
 */
package com.massyframework.beanskin.launcher.scanning;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.function.Consumer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.massyframework.beanskin.launcher.scanning.maven.DefaultMavenProjectRepository;
import com.massyframework.beanskin.util.version.Version;


/**
 * 基于本地文件的资源扫描
 * @author huangkh
 *
 */
class ClassPathResourceScanner implements ModuleResourcesScanner<URL> {

	private Logger logger = LoggerFactory.getLogger(ClassPathResourceScanner.class);
	private String PROTOCOL = "file";
	private DefaultMavenProjectRepository mavenProjectRepository;
	

	/**
	 * 
	 */
	public ClassPathResourceScanner() {
		this.mavenProjectRepository = new DefaultMavenProjectRepository();
		this.mavenProjectRepository.init();
	}
	

	@Override
	public void scanning(URL scope, Consumer<ModuleResources> action) {
		if (!scope.getProtocol().equals(PROTOCOL)) {
			return;
		}
		
		File pomXml = this.doLocatePomXml(scope);
		this.doScanGroupId(new File(scope.getFile()), pomXml, action);
	}

	/**
	 * 扫描目录
	 * @param dir {@link File}, 目录
	 * @param pomXml {@link File}, pomXml文件
	 * @param action {@link Consumer}, 消费者
	 */
	protected void doScanGroupId(File dir, File pomXml, Consumer<ModuleResources> action) {
		//第一层目录: groupId
		File[] files = dir.listFiles();
		if (files == null) return;
		
		for (File file: files) {
			if (file.isDirectory()) {
				String groupId = file.getName();
				this.doScanModuleId(file, groupId, pomXml, action);
			}
		}
	}
	
	protected void doScanModuleId(File dir, String groupId, File pomXml, Consumer<ModuleResources> action) {
		//第二层 模块编号
		File[] files = dir.listFiles();
		if (files == null) return;
		
		for (File file: files) {
			if (file.isDirectory()) {
				String moduleId = file.getName();
				this.doScanModuleVersion(file, groupId, moduleId, pomXml, action);
			}
		}
	}
	
	/**
	 * 扫描模块版本
	 * @param dir {@link File}, 目录
	 * @param groupId {@link String}, 组编号
	 * @param moduleId {@link String}, 模块编号
	 * @param pomXml {@link File}, pom.xml文件
	 * @param action {@link Consumer}， 模块资源消费者
	 */
	protected void doScanModuleVersion(File dir, String groupId, String moduleId, 
			File pomXml, Consumer<ModuleResources> action) {
		//第二层 版本
		File[] files = dir.listFiles();
		if (files == null) return;
		
		for (File file: files) {
			if (file.isDirectory()) {
				String text = file.getName();
				
				try {
					Version.valueOf(text);
				}catch(Exception e) {
					if (logger.isErrorEnabled()) {
						logger.error(text.concat(" is not valid version format, skip scanning dir:".concat(dir.getPath())));
					}
					continue;
				}
					
				ModuleResources.Builder builder = 
						ModuleResources.newBuilder();
				
				this.doScanModuleResources(file, builder,
						groupId.concat(File.separator).concat(moduleId).concat(File.separator).concat(text), pomXml);
								
				if (pomXml != null) {	
					builder.groupId(groupId).moduleId(moduleId).version(text).pomFile(pomXml);
				}
				action.accept(builder.build());
				
			}
		}
	}
	
	/**
	 * 扫描模块资源
	 * @param dir {@link File}, 目录
	 * @param builder {@link ModuleResources.Builder}, 模块资源构建器
	 * @param pomXml {@link File}, pom.xml文件
	 */
	protected void doScanModuleResources(File dir, ModuleResources.Builder builder, String path,  File pomXml){
		File[] files = dir.listFiles();
		if (files == null) return;
		
		for (File file: files) {
			if (file.isDirectory()) {
				this.doScanModuleResources(file, builder, path.concat(File.separator).concat(file.getName()), pomXml);
			}else {
				try {
					builder.addResource(path.concat(File.separator).concat(file.getName()),  file.toURI().toURL());
				} catch (MalformedURLException e) {
				}
			}
		}
	}
	
	/**
	 * 定位pom.xml文件
	 * @param url {@link URL} 
	 * @return
	 */
	public File doLocatePomXml(URL url) {
		if (url.getProtocol().equals(PROTOCOL)) {
			File dir = new File(url.getFile());
			return this.doLocatePomXml(dir, 3);
		}
		
		return null;
	}
		
	/**
	 * 递归定位pom.xml
	 * @param file
	 * @param deep
	 * @return
	 */
	protected File doLocatePomXml(File dir, int deep) {
		if (dir == null) return null;
		if (deep == 0) {
			File result = new File(dir, "pom.xml");
			return result.exists() ? result : null;
		}
		
		return this.doLocatePomXml(dir.getParentFile(), deep -1);
	}
}
